home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #9 / Amiga Plus CD - 2004 - No. 09.iso / amigaplus / tools / amigaos4_only / tunnel / tunnel.c < prev   
C/C++ Source or Header  |  2004-08-03  |  8KB  |  336 lines

  1. /*
  2. ** A simple tunnel for OS4
  3. ** By Peter Gordon (pete@shagged.org)
  4. **
  5. ** Enjoy :)
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <math.h>
  11.  
  12. #include <exec/types.h>
  13. #include <exec/ports.h>
  14. #include <exec/interfaces.h>
  15. #include <exec/libraries.h>
  16. #include <dos/dos.h>
  17. #include <intuition/intuition.h>
  18.  
  19. #include <proto/exec.h>
  20. #include <proto/dos.h>
  21. #include <proto/intuition.h>
  22. #include <proto/Picasso96API.h>
  23. #include <proto/graphics.h>
  24.  
  25. #define fsqr(x) pow(x,2)
  26. #define min(x,y) x<y ? x : y
  27.  
  28. // Libraries
  29. struct Library *IntuitionBase = NULL;
  30. struct Library *P96Base = NULL;
  31. struct Library *GfxBase = NULL;
  32.  
  33. // Interfaces
  34. struct IntuitionIFace *IIntuition;
  35. struct P96IFace *IP96;
  36. struct GraphicsIFace *IGraphics;
  37. struct ExecIFace *IExec;
  38. struct DOSIFace *IDOS;
  39.  
  40. struct Window *win;
  41. struct BitMap *bm;
  42.  
  43. UBYTE txtr[65536*3]; // texture
  44. UWORD uvmap[232083];
  45.  
  46.  
  47. /*
  48. ** A small routine to open a library and get its default
  49. ** interface, and report errors if anything fails.
  50. */
  51. BOOL getLibIFace( struct Library **libbase, char *libname, int version, struct Interface **ifaceptr )
  52. {
  53.   *libbase = IExec->OpenLibrary( libname, version );
  54.   if( *libbase == NULL )
  55.   {
  56.     printf( "Unable to open '%s' version %d\n", libname, version );
  57.     return FALSE;
  58.   }
  59.   *ifaceptr = IExec->GetInterface( *libbase, "main", 1, NULL );
  60.   if( *ifaceptr == NULL )
  61.   {
  62.     printf( "Unable to get the main interface for '%s'\n", libname );
  63.     return FALSE;
  64.   }
  65.   return TRUE;
  66. }
  67.  
  68. BOOL init( void )
  69. {
  70.   BPTR h;
  71.  
  72.   if( !getLibIFace( &IntuitionBase, "intuition.library", 50, (struct Interface **)&IIntuition ) ) return FALSE;
  73.   if( !getLibIFace( &GfxBase, "graphics.library", 48, (struct Interface **)&IGraphics ) ) return FALSE;
  74.   if( !getLibIFace( &P96Base, "Picasso96API.library", 2, (struct Interface **)&IP96 ) ) return FALSE;
  75.  
  76.   h = IDOS->Open( "texture.raw", MODE_OLDFILE );
  77.   if( !h )
  78.   {
  79.     printf( "Unable to open texture.raw\n" );
  80.     return FALSE;
  81.   }
  82.  
  83.   IDOS->Read( h, txtr, 65536*3 );
  84.   IDOS->Close( h );
  85.  
  86.   bm = IP96->p96AllocBitMap( 320, 240, 24, 0, NULL, RGBFB_R8G8B8 );
  87.   if( !bm ) return FALSE;  
  88.  
  89.   win = IIntuition->OpenWindowTags( NULL,
  90.               WA_Left,         28,
  91.               WA_Top,          28,
  92.               WA_InnerWidth,  320,
  93.               WA_InnerHeight, 240,
  94.               WA_Title,       "Wheeeee !",
  95. #ifdef PLANES
  96.               WA_ScreenTitle, "Planes Demo ©2004 Peter Gordon (pete@shagged.org)",
  97. #else
  98.   #ifdef BOXTUNNEL
  99.               WA_ScreenTitle, "BoxTunnel Demo ©2004 Peter Gordon (pete@shagged.org)",
  100.   #else
  101.     #ifdef QUADPLANE
  102.               WA_ScreenTitle, "Quadplane Demo ©2004 Peter Gordon (pete@shagged.org)",
  103.     #else
  104.               WA_ScreenTitle, "Tunnel Demo ©2004 Peter Gordon (pete@shagged.org)",
  105.     #endif
  106.   #endif
  107. #endif
  108.               WA_DragBar,     TRUE,
  109.               WA_DepthGadget, TRUE,
  110.               WA_CloseGadget, TRUE,
  111.               WA_Activate,    TRUE,
  112.               WA_IDCMP,       IDCMP_CLOSEWINDOW,
  113.               TAG_DONE );
  114.   if( !win ) return FALSE;
  115.  
  116.   return TRUE;
  117. }
  118.  
  119. void shutdown( void )
  120. {
  121.   if( win ) IIntuition->CloseWindow( win );
  122.   if( bm ) IP96->p96FreeBitMap( bm );
  123.   if( P96Base ) IExec->CloseLibrary( P96Base );
  124.   if( GfxBase ) IExec->CloseLibrary( GfxBase );
  125.   if( IntuitionBase ) IExec->CloseLibrary( IntuitionBase );
  126. }
  127.  
  128. // Cam Rotate Y, Cam Rotate Z, Cam position Z
  129. void tunnel( double cry, double crz, double cz )
  130. {
  131.   double len,vx,vy,vz;
  132.   double dx,dy,dz;
  133.   double a,delta,t;
  134.   double fx,ys,yc,zs,zc,ys2,yc2;
  135.   ULONG pk,px,py,lock;
  136.   UWORD tu,tv,tm;
  137.   ULONG u1, u2, v1, v2, d1, d2;
  138.   UBYTE *bptr;
  139.   struct RenderInfo rinf;
  140.  
  141.   ys = sin( cry );
  142.   ys2 = ys*256;
  143.   yc = cos( cry );
  144.   yc2 = yc*256;
  145.   zs = sin( crz );
  146.   zc = cos( crz );
  147.  
  148.   pk = 0;
  149.  
  150.   for( py=0; py<31; py++ )
  151.   {
  152.     for( px=0; px<41; px++ )
  153.     {
  154.       dx = (double)(px<<3)-160;
  155.       dy = (double)(py<<3)-122;
  156.  
  157.       fx = zs*dy+zc*dx; // Rotate around Z axis
  158.  
  159.       dy = zc*dy-zs*dx; // Rotate around Y axis
  160.       dx = yc*fx-ys2;
  161.       dz = ys*fx+yc2;
  162.  
  163. #ifdef PLANES
  164.       a = fsqr(dx);
  165. #else
  166.   #ifdef BOXTUNNEL
  167.       a = abs(dx) < abs(dy) ? fsqr(dy) : fsqr(dx);
  168.   #else
  169.     #ifdef QUADPLANE
  170.       a = abs(dx) < abs(dy) ? fsqr(dx) : fsqr(dy);
  171.     #else
  172.       a = (fsqr(dx) + fsqr(dy));
  173.     #endif
  174.   #endif
  175. #endif
  176.       if( a >= 0 )
  177.       {
  178.         delta = a*131072;
  179.  
  180.         t = -fabs( sqrt( delta )/a );
  181.  
  182.         vx = dx*t;
  183.         vy = dy*t;
  184.         vz = dz*t;
  185.  
  186.         tm = ((UWORD)fabs(t*10));
  187.  
  188.         uvmap[ pk++ ] = (UWORD)(fabs(vz+cz)*0.2);
  189.         uvmap[ pk++ ] = (UWORD)(fabs(atan2(vy,vx)*81.4873309));
  190.         uvmap[ pk ] = 256 - (min( tm, 256 ));
  191.  
  192.         pk+=22;
  193.       } else pk+=24;
  194.     }
  195.     pk += 6720;
  196.   }
  197.  
  198.   pk=0;
  199.  
  200.   // Interpolate down
  201.   for( py=0; py<30; py++ )
  202.   {
  203.     for( px=0; px<41; px++ )
  204.     {
  205.       u2 = uvmap[pk];
  206.       u1 = uvmap[pk+7704]-u2;
  207.       u2 = (u2<<3) + u1;
  208.       v2 = uvmap[pk+1];
  209.       v1 = uvmap[pk+7705]-v2;
  210.       v2 = (v2<<3) + v1;
  211.       d2 = uvmap[pk+2];
  212.       d1 = uvmap[pk+7706]-d2;
  213.       d2 = (d2<<3) + d1;
  214.       for( tu=963; tu<7704; tu+=963 )
  215.       {
  216.         uvmap[pk+tu] = u2>>3;
  217.         uvmap[pk+tu+1] = v2>>3;
  218.         uvmap[pk+tu+2] = d2>>3;
  219.         u2 += u1;
  220.         v2 += v1;
  221.         d2 += d1;
  222.       }
  223.       pk += 24;
  224.     }
  225.     pk += 6720;
  226.   }
  227.  
  228.   pk = 0;
  229.  
  230.   // Interpolate across
  231.   for( py=0; py<240; py++ )
  232.   {
  233.     for( px=0; px<40; px++ )
  234.     {
  235.       u2 = uvmap[pk++];
  236.       u1 = uvmap[pk+23]-u2;
  237.       u2 = (u2<<3) + u1;
  238.       v2 = uvmap[pk++];
  239.       v1 = uvmap[pk+23]-v2;
  240.       v2 = (v2<<3) + v1;
  241.       d2 = uvmap[pk++];
  242.       d1 = uvmap[pk+23]-d2;
  243.       d2 = (d2<<3) + d1;
  244.       for( tu=1; tu<8; tu++ )
  245.       {
  246.         uvmap[pk++] = u2>>3;
  247.         uvmap[pk++] = v2>>3;
  248.         uvmap[pk++] = d2>>3;
  249.         u2 += u1;
  250.         v2 += v1;
  251.         d2 += d1;
  252.       }
  253.     }
  254.     pk+=3;
  255.   }
  256.  
  257.   lock = IP96->p96LockBitMap( bm, (UBYTE *)&rinf, (ULONG)sizeof( struct RenderInfo ) );
  258.   if( !lock ) return;
  259.  
  260.   bptr = (UBYTE *)rinf.Memory;
  261.  
  262.   for( py=0; py<231120; py+=963 )
  263.   {
  264.     u1 = py;
  265.     for( px=0; px<320; px++ )
  266.     {
  267.       tv = (((uvmap[u1++]&255)<<8)|(uvmap[u1+1]&255))*3;
  268.       tm = (UBYTE)((txtr[tv++]*uvmap[++u1])>>8);
  269.       *(bptr) = (*(bptr++)+tm)>>1;
  270.       tm = (UBYTE)((txtr[tv++]*uvmap[u1])>>8);
  271.       *(bptr) = (*(bptr++)+tm)>>1;
  272.       tm = (UBYTE)((txtr[tv++]*uvmap[u1++])>>8);
  273.       *(bptr) = (*(bptr++)+tm)>>1;
  274. /*
  275.       *(bptr++) = (UBYTE)((txtr[tv++]*uvmap[++u1])>>8);
  276.       *(bptr++) = (UBYTE)((txtr[tv++]*uvmap[u1])>>8);
  277.       *(bptr++) = (UBYTE)((txtr[tv++]*uvmap[u1++])>>8);
  278. */
  279.     }
  280.   }
  281.  
  282.   IP96->p96UnlockBitMap( bm, lock );
  283. }
  284.  
  285. int main( void )
  286. {
  287.   struct DateStamp start_ds, end_ds;
  288.   ULONG frames = 0, ticks;
  289.  
  290.   if( init() )
  291.   {
  292.     BOOL done = FALSE;
  293.     ULONG wsig, sigs;
  294.     struct IntuiMessage *msg;
  295.     double cry, crz, cz;
  296.  
  297.     wsig = (1L<<win->UserPort->mp_SigBit);
  298.  
  299.     IDOS->DateStamp( &start_ds );
  300.  
  301.     while( !done )
  302.     {
  303. //      IGraphics->WaitTOF();
  304.       tunnel( cry, crz, cz );
  305.       IGraphics->BltBitMapRastPort( bm, 0, 0, win->RPort, win->BorderLeft, win->BorderTop, 320, 240, 0x0C0 );
  306.       cry += 0.03;
  307.       crz -= 0.01;
  308.       cz  -= 80;
  309.       sigs = IExec->SetSignal( 0L, 0L );
  310.  
  311.       frames++;
  312.        
  313.       if( sigs & SIGBREAKF_CTRL_C ) done = TRUE;
  314.       if( sigs & wsig )
  315.       {
  316.         while( msg = (struct IntuiMessage *)IExec->GetMsg( win->UserPort ) )
  317.         {
  318.           if( msg->Class == IDCMP_CLOSEWINDOW ) done = TRUE;
  319.           IExec->ReplyMsg( (struct Message *)msg );
  320.         }
  321.       }
  322.     }
  323.  
  324.     IDOS->DateStamp(&end_ds);
  325.  
  326.     ticks = (end_ds.ds_Days-start_ds.ds_Days) * 86400*TICKS_PER_SECOND
  327.             +(end_ds.ds_Minute-start_ds.ds_Minute) * 60*TICKS_PER_SECOND
  328.             +(end_ds.ds_Tick-start_ds.ds_Tick);
  329.  
  330.     printf( "FPS: %d\n", (TICKS_PER_SECOND * frames) / ticks+1 );
  331.   }
  332.  
  333.   shutdown();
  334.   return 0;
  335. }
  336.